package com.xiao.community.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiao.group.common.utils.PageUtils;
import com.xiao.group.common.utils.Query;

import com.xiao.community.dao.PintuanDao;
import com.xiao.community.entity.PintuanEntity;
import com.xiao.community.service.PintuanService;


@Service("pintuanService")
public class PintuanServiceImpl extends ServiceImpl<PintuanDao, PintuanEntity> implements PintuanService {

    @Autowired
    private RestHighLevelClient client;

    @Override
    public PageUtils queryPage(Map<String, Object> params,PintuanEntity pintuanEntity) throws IOException {

        SearchRequest searchRequest = new SearchRequest("pintuan");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if (pintuanEntity !=null){
            if (pintuanEntity.getPintuanName() !=null && !pintuanEntity.getPintuanName().equals("")){
                boolQueryBuilder.filter(QueryBuilders.matchQuery("pintuanName",pintuanEntity.getPintuanName()));
            }
            if (pintuanEntity.getGoodsName() !=null && !pintuanEntity.getGoodsName().equals("")){
                boolQueryBuilder.filter(QueryBuilders.matchQuery("goodsName",pintuanEntity.getGoodsName()));
            }
            if (pintuanEntity.getPintuanPricex() !=null){
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("pintuanPrice").gte(pintuanEntity.getPintuanPricex()));
            }
            if (pintuanEntity.getPintuanPriced() !=null){
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("pintuanPrice").lte(pintuanEntity.getPintuanPriced()));
            }
        }

        Integer page = Integer.valueOf((String) params.get("page"));
        Integer limit = Integer.valueOf((String) params.get("limit"));

        searchSourceBuilder.from((page-1)*limit);
        searchSourceBuilder.size(limit);

        if (pintuanEntity.getGoodsName() !=null){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            HighlightBuilder.Field highlightTitle =
                    new HighlightBuilder.Field("goodsName");
            highlightTitle.highlighterType("unified");
            highlightBuilder.field(highlightTitle);
            highlightBuilder.preTags("<span style='color:red'>");
            highlightBuilder.postTags("</span>");
            searchSourceBuilder.highlighter(highlightBuilder);
        }
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();
        SearchHit[] searchHits = hits.getHits();
        ArrayList<Object> arrayList = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            PintuanEntity parseObject = JSON.parseObject(sourceAsString, new TypeReference<PintuanEntity>() {
            });
            if (pintuanEntity.getGoodsName() !=null){
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlight = highlightFields.get("goodsName");
                if (highlight !=null) {
                    Text[] fragments = highlight.fragments();
                    String fragmentString = fragments[0].string();
                    parseObject.setGoodsName(fragmentString);
                }
            }
            arrayList.add(parseObject);
        }
        return new PageUtils(arrayList,(int)numHits,limit,page);
    }

    @Override
    public PintuanEntity selectByGoodsId(Integer goodsId) {

        return baseMapper.selectOne(new QueryWrapper<PintuanEntity>().eq("goods_id",goodsId));
    }

    @Override
    public PintuanEntity selectByGood(Integer pintuanId) {
        QueryWrapper<PintuanEntity> queryWrapper = new QueryWrapper<>();
        QueryWrapper<PintuanEntity> id = queryWrapper.eq("pintuan_id", pintuanId);
        return baseMapper.selectOne(id);
    }

    @Override
    public Integer selectByNum(Integer pintuanId) {
        return baseMapper.selectByNum(pintuanId);
    }


}